<?php

require_once('user_dbc.class.php');
require_once('user_md5pwd_dbc.class.php');

class User_BFPwd_DBC extends User_DBC {
	private $db_table_prefix;
	private $password_bf;
	private $salt;
	private $password_clear_form = true; //indicates if $password is in clear form or some already hashed form

	public function set_password($password, $clear_form = true) {
		parent::set_password($password);
		$this->set_password_clear_form($clear_form);
	}


	public function set_password_bf($password_bf) {
		$this->password_bf = $password_bf;
	}


	public function get_password_bf() {
		return $this->password_bf;
	}


	public function set_salt($salt) {
		$this->salt = $salt;
	}


	public function get_salt() {
		return $this->salt;
	}


	public function set_password_clear_form($password_clear_form) {
		$this->password_clear_form = $password_clear_form;
	}


	public function get_password_clear_form() {
		return $this->password_clear_form;
	}


	protected function generate_salt() {
		// 2a bellow means "use blowfish". $10$ means use 10 recursice calls when generating salt. 
		$salt = '$2a$10$'.substr(str_replace('+', '.', base64_encode(pack('N4', mt_rand(), mt_rand(), mt_rand(), mt_rand()))), 0, 21) . '$';
		
		return $salt;
	}


	public function load_by_id(DB_Connection $dbc, $id) {
		global $_MODULES_REGISTER;
		
		$ret = false;
		
		$sql = "select username, password, disabled from " . $this->get_db_table_prefix() . "users where id = $id";
		$rez = $dbc->execute($sql);
		
		if (!$rez->is_eof()) {
			$rez_obj = $rez->fetch_object();
			$this->set_id($id);
			$this->set_username($rez_obj->USERNAME);
			$this->set_password_bf($rez_obj->PASSWORD, false);
			if (strlen($rez_obj->PASSWORD) == 60) { //workaround some odd cases during upgrade
				$this->set_salt(substr($rez_obj->PASSWORD, 0, -32) . '$');
			} else {
				$this->set_salt('');
			}
			$this->set_disabled($rez_obj->DISABLED);
			
			$ret = $id;
		}
		
		return $ret;
	}


	protected function insert(DB_Connection $dbc) {
		$ret = false;
		
		$id = $dbc->generate_id($this->get_db_table_prefix() . "users_seq");
		if ($id) {
			
			$username = addslashes($this->get_username());
			if ($this->get_password_clear_form()) {
				$salt = $this->get_salt();
				if (!$salt) {
					$salt = $this->generate_salt();
					$this->set_salt($salt);
				}
				$password = crypt($this->get_password(), $salt);
				$this->set_password($password, false);
			} else {
				throw Tangra_Module_Exception("Password is not in clear form. Cannot crypt because will create a mess.");
			}
			$disabled = $this->get_disabled();
			
			$sql = "insert into " . $this->get_db_table_prefix() . "users " . "(id, " . "username, " . "password, " . "disabled) " . "values " .
				 "($id, " . "'$username', " . "'$password', " . $disabled . ") ";
				
				$dbc->execute($sql);
				$ret = $id;
			} else {
				throw new TE_Exception("ID not generated - " . $this->get_db_table_prefix() . "users_seq");
			}
			
			return $ret;
		}


		protected function update(DB_Connection $dbc) {
			$username = addslashes($this->get_username());
			if ($this->get_password_clear_form()) {
				$salt = $this->get_salt();
				if (!$salt) {
					$salt = $this->generate_salt();
					$this->set_salt($salt);
				}
				$password = crypt($this->get_password(), $salt);
				$this->set_password($password, false);				
			} else {
				throw Tangra_Module_Exception("Password is not in clear form. Cannot crypt because will create a mess.");
			}
			$disabled = $this->get_disabled();
			
			$sql = "update " . $this->get_db_table_prefix() . "users set " . "username = '$username', " . "password = '$password', " .
				 "disabled = $disabled " . "where id = " . $this->get_id();
				
				$dbc->execute($sql);
				
				return $this->get_id();
			}


			public static function check_login(DB_Connection $dbc, $username, $password, $prefix = '') {
				$ret = false;
				
				$sql = "select id, password from " . $prefix . "users where username = '" . $username . "' and disabled = 0";
				
				$rez = $dbc->execute($sql);
				if (!$rez->is_eof()) {
					$rez_obj = $rez->fetch_object();
					
					// we check if old (md5) password hashing is used
					if (strlen($rez_obj->PASSWORD) == 60) { // new blowfish style is used			
								
						$salt = substr($rez_obj->PASSWORD, 0, -32) . '$';
						if ($rez_obj->PASSWORD == crypt($password, $salt)) {
							$ret = new User_BFPwd_DBC($prefix);
							$ret->load_by_id($dbc, $rez_obj->ID);
						}
					} elseif (strlen($rez_obj->PASSWORD) == 32) { // old md5 password hashing is used
						if ($rez_obj->PASSWORD == md5($password)) {
							$ret = new User_Md5Pwd_DBC($prefix);
							$ret->load_by_id($dbc, $rez_obj->ID);
						}
					} else { 
						throw new Tangra_Module_Exception("Login failed because password lenght is uncompatible.");
					}
					
				}
				
				return $ret;
			}


			public static function get_sql_for_grid() {
				$sql = "select id, username, disabled from users ";
				
				return $sql;
			}


			public static function get_sql_count_for_grid() {
				$sql = "select count(id) as total_rows from users ";
				
				return $sql;
			}
		}